import * as step from '@flow-step/step-toolkit'
import {RosInterface} from './ros'
import {
    UpdateStackRequest,
    UpdateStackRequestParameters,
    UpdateStackResponse
} from '@alicloud/ros20190910'
import {IParams} from './params'
import {getParameters} from './getParameters'
import {getTemplateBody} from './getTemplate'
import {isNotEmpty} from './util'


export async function updateStack(params: IParams, ros: RosInterface, stackId: string) {
    let updateStackParams: any = new UpdateStackRequest()
    const parameters = getParameters()
    const templateBody = getTemplateBody()
    let stackParameters: any[] = []
    updateStackParams['regionId'] = params.REGION_ID
    updateStackParams['templateBody'] = templateBody
    updateStackParams['stackId'] = stackId
    if (isNotEmpty(params.TIMEOUT_MINUTES) && params.TIMEOUT_MINUTES !== 0) {
        updateStackParams['timeoutInMinutes'] = params.TIMEOUT_MINUTES
    } else {
        updateStackParams['timeoutInMinutes'] = 60
    }
    if (isNotEmpty(params.RAM_ROLE_NAME)) {
        updateStackParams['ramRoleName'] = params.RAM_ROLE_NAME
    } else {
        updateStackParams['ramRoleName'] = 'AliyunROSFullRole'
    }
    if (parameters) {
        for (let [paramKey, paramValue] of parameters) {
            stackParameters.push(new UpdateStackRequestParameters({
                parameterKey: paramKey,
                parameterValue: paramValue
            }))
        }
        step.info(`UpdateStack params is ${JSON.stringify(stackParameters, null, 2)}`);
        updateStackParams['parameters'] = stackParameters
    }
    const request: UpdateStackRequest = new UpdateStackRequest(updateStackParams)
    let response: UpdateStackResponse
    step.info(`UpdateStack request is ${JSON.stringify(updateStackParams, null, 2)}`);
    try {
        response = await ros.updateStack(request)
    } catch (error: any)  {
        if (error.statusCode != 200) {
            if (error.data?.Message.startsWith('Update the completely same stack')) {
                step.info(`Stack ${params.STACK_NAME} has no changes. No update needed.`);
                return stackId
            }
            if (error.data?.Code == 'LastTokenProcessing') {
                step.info(`Stack ${params.STACK_NAME} is already updating.`);
                return stackId
            }
        }
        step.error(`Failed to UpdateStack. Code: ${error?.code}, Message: ${error.data?.Message}, RequestId: ${error?.data.RequestId}`);
        if (!isNotEmpty(error.data?.Message)) {
            step.error(`Unexpected UpdateStack error. Error: ${JSON.stringify(error, null, 2)}`);
        }
        return false
    }

    const StackId = response.body?.stackId

    if (isNotEmpty(StackId)) {
        return StackId
    } else {
        return false
    }
}